﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxEditors;
using System.Configuration;
using DevExpress.Web.ASPxCallback;

namespace TireService.Web.View.ResourceView
{
    public partial class ContainerList : System.Web.UI.Page
    {

        #region Public Properties

        public int ContainerId
        {
            get
            {
                if (ViewState["_containerid"] != null)
                    return (int)ViewState["_containerid"];
                else
                    return 0;
            }
            set
            {
                ViewState["_containerid"] = value;
            }
        }

        public List<int> Printlabels
        {
            get
            {
                if (ViewState["_printlabelse"] != null)
                    return (List<int>)ViewState["_printlabelse"];
                else
                    return null;
            }
            set
            {
                ViewState["_printlabelse"] = value;
            }
        }

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            if (Page.IsPostBack != true)
            {

            }

            // Bind container data to gridview
            BindContainerData(db);
            try
            {
                int containerid = Convert.ToInt32(gvContainer.GetRowValues(gvContainer.FocusedRowIndex, "ContainerId"));
                BindContainerCargoRoom(db, containerid);
            }
            catch (Exception)
            {
                // Nothing - no container selected
            }


            // Change gridview pagesize based on dropdownlist
            gvContainer.SettingsPager.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);

            // Dispose connection to database
            db.Dispose();
        }

        /// <summary>
        /// Function that bind container data to gridview
        /// </summary>
        /// <param name="db">Connection to database</param>
        private void BindContainerData(TireServiceDB db)
        {
            gvContainer.DataSource = db.GetContainers();
            gvContainer.DataBind();

            // Prepare data for editmode of container
            GridViewDataComboBoxColumn ddlCountry = gvContainer.Columns["CountryDropdown"] as GridViewDataComboBoxColumn;
            ddlCountry.PropertiesComboBox.ValueType = typeof(int);
            ddlCountry.PropertiesComboBox.DataSource = db.GetCountries();
            ddlCountry.PropertiesComboBox.TextField = "CountryName";
            ddlCountry.PropertiesComboBox.ValueField = "CountryId";
            ddlCountry.PropertiesComboBox.DropDownStyle = DropDownStyle.DropDownList;
            ddlCountry.PropertiesComboBox.IncrementalFilteringMode = IncrementalFilteringMode.StartsWith;
        }

        /// <summary>
        /// Function that bind containercargo rooms to gridview
        /// </summary>
        /// <param name="db">Connection to database</param>
        /// <param name="ContainerId">Id on container</param>
        private void BindContainerCargoRoom(TireServiceDB db, int ContainerId)
        {
            // Bind to gridview
            gvContainerCargoRoom.DataSource = db.GetContainerCargoRoomTireSetViews(ContainerId).OrderBy(p => p.CargoRoomNumber);
            gvContainerCargoRoom.DataBind();
        }

        #region Private Functions

        /// <summary>
        /// Function that change grouping in order gridview
        /// </summary>
        /// <param name="ViewIndex">Integer setting the grouping mode</param>
        protected void GroupOrderData(int ViewIndex)
        {
            gvContainer.ClearSort();
            gvContainer.GroupSummary.Clear();
            switch (ViewIndex)
            {
                case 0:
                    // Nothing - clear grouping

                    break;
                case 1:
                    gvContainer.GroupBy(gvContainer.Columns["City"]);

                    break;
                //case 2:
                //    gvOrder.GroupBy(gvOrder.Columns["CustomerNumber"]);

                //    break;
                //case 3:
                //    gvOrder.GroupBy(gvOrder.Columns["PhotoDate"]);
                //    gvOrder.GroupBy(gvOrder.Columns["CustomerNumber"]);

                //break;
            }
            gvContainer.ExpandAll();
        }

        /// <summary>
        /// Function for generating a uniq number for container
        /// </summary>
        /// <param name="db">Connection to database</param>
        /// <param name="ZipCode">Zipcode area container is placed within</param>
        /// <param name="number">Number for last container in this area</param>
        /// <returns>String with container number</returns>
        protected string GenerateContainerNumber(TireServiceDB db, int ZipCode, int? number)
        {
            int countcontainer = 0;

            // Calculate container number
            if (number != null)
            {
                countcontainer = Convert.ToInt32(number) + 1;
            }
            else
            {
                countcontainer = db.CountContainerWithZipCode(ZipCode);
            }

            string containernumber = ZipCode.ToString() + "-" + (countcontainer + 1).ToString();
            Container existing = db.GetContainer(containernumber);

            if (existing != null)
            {
                return GenerateContainerNumber(db, ZipCode, countcontainer);
            }
            else
            {
                return containernumber;
            }
        }

        #endregion

        #region Control Functions

        /// <summary>
        /// Button function for creating a new container
        /// </summary>
        protected void btnNewContainer_Click(object sender, EventArgs e)
        {
            // TODO: Write javascript code
            //// Go to edit mode
            //Session["ContainerId"] = null;
            //Response.Redirect("~/Casehandling/EditContainer.aspx");
        }

        /// <summary>
        /// Button function for export of gridview
        /// </summary>
        protected void btnExport_Click(object sender, EventArgs e)
        {
            if (ddlExport.Value == "0")
            {
                gvExport.WritePdfToResponse();
            }

            if (ddlExport.Value == "1")
            {
                gvExport.WriteXlsToResponse();
            }

            if (ddlExport.Value == "2")
            {
                gvExport.WriteCsvToResponse();
            }

            if (ddlExport.Value == "3")
            {
                gvExport.WriteRtfToResponse();
            }
        }
        
        /// <summary>
        /// Dropdown list function that change gridview grouping when selected item is changed
        /// </summary>
        protected void ddlView_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Group data
            GroupOrderData(Convert.ToInt32(ddlView.SelectedValue));
        }

        #endregion

        protected void callBackAddCargoRooms_Callback(object sender, CallbackEventArgs e)
        {
            // Send email to selected customers
            string[] param = e.Parameter.Split(',');

            // Instantiate database
            TireServiceDB db = new TireServiceDB();

            int addamount = Convert.ToInt32(param[1]);

            // Calculate last cargo room number
            int LastCargoRoomNumber = db.GetLastContainerCargoRoomNumber(Convert.ToInt32(param[0]));

            // Fetch Container
            Container container = db.GetContainer(Convert.ToInt32(param[0]));

            for (int i = 0; i < addamount; i++)
            {
                ContainerCargoRoom cargoroom = new ContainerCargoRoom();
                
                container.ContainerCargoRooms.Add(cargoroom);
                cargoroom.ContainerId = Convert.ToInt32(param[0]);
                cargoroom.CargoRoomNumber = i + LastCargoRoomNumber + 1;

                db.AddContainerCargoRoom(cargoroom);
            }

            // Update container with new spacecapacity
            container.SpaceCapacity = container.SpaceCapacity + addamount;

            // Commit changes to database
            db.SubmitChanges();

            // Refresh gridviews
            BindContainerData(db);
            BindContainerCargoRoom(db, Convert.ToInt32(param[0]));

            // Dispose database connection
            db.Dispose();
        }


        #region GridView Functions

        /// <summary>
        /// Gridview function that change field data for unbound fields
        /// </summary>
        protected void gvContainer_CustomUnboundColumnData(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewColumnDataEventArgs e)
        {
            // Format UnBoundColumn UsedCapacity: Show used capacity
            if (e.Column.FieldName == "UsedCapacity")
            {
                // Get containerid
                int containerid = Convert.ToInt32(e.GetListSourceFieldValue("ContainerId"));

                TireServiceDB db = new TireServiceDB();

                // Change field value
                e.Value = db.GetContainerUsedCapacity(containerid).First().UsedCapacity.ToString();
                
                db.Dispose();
            }

            // Format UnBoundColumn FreeCapacity: Show free capacity
            if (e.Column.FieldName == "FreeCapacity")
            {
                // Get containerid
                int containerid = Convert.ToInt32(e.GetListSourceFieldValue("ContainerId"));

                TireServiceDB db = new TireServiceDB();

                // Change field value
                e.Value = db.GetContainerFreeCapacity(containerid).First().FreeCapacity.ToString();

                db.Dispose();
            }
        }

        /// <summary>
        /// Gridview function for creating container
        /// </summary>
        protected void gvContainer_RowInserting(object sender, DevExpress.Web.Data.ASPxDataInsertingEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            // Reset id
            this.ContainerId = 0;

            Container container = new Container();

            container.Address = Convert.ToString(e.NewValues["Address"]);
            container.ZipCode = Convert.ToInt32(e.NewValues["ZipCode"]);
            container.City = Convert.ToString(e.NewValues["City"]);
            container.CountryId = Convert.ToInt32(e.NewValues["CountryId"]);
            container.InActive = Convert.ToBoolean(e.NewValues["InActive"]);
            container.NoneMoveableContainer = Convert.ToBoolean(e.NewValues["NoneMoveableContainer"]);
            container.ContainerNumber = GenerateContainerNumber(db, container.ZipCode, null);

            // Calculate longitude and latitude for address
            try
            {
                string primaryAddress = container.Address + ", " + container.ZipCode + " " + container.City + ", " + db.GetCountryName(container.CountryId);
                GoogleMaps googleMapAPI = new GoogleMaps(ConfigurationSettings.AppSettings["MapKey"]);
                double[] LongLatPrimary = googleMapAPI.GetLongLatCoordinates(primaryAddress);
                container.Longitude = LongLatPrimary[0];
                container.Latitude = LongLatPrimary[1];
            }
            catch (Exception ex)
            {
                // Error calculating longitude and latitude - values will be set to null
            }
            
            // Get number of cargo rooms to create for new container
            ASPxSpinEdit txtAddContainerCargoRooms = (ASPxSpinEdit)gvContainer.FindEditFormTemplateControl("txtAddContainerCargoRooms");
            int addrooms = Convert.ToInt32(txtAddContainerCargoRooms.Text);

            for (int i = 0; i < addrooms; i++)
            {
                ContainerCargoRoom cargoroom = new ContainerCargoRoom();

                container.ContainerCargoRooms.Add(cargoroom);
                cargoroom.CargoRoomNumber = i + 1;

                db.AddContainerCargoRoom(cargoroom);
            }

            // Update container spacecapacity
            container.SpaceCapacity = addrooms;

            db.AddContainer(container);

            // Commit changes to database
            db.SubmitChanges();

            // End edit mode
            e.Cancel = true;
            gvContainer.CancelEdit();

            // Reset edit mode
            this.ContainerId = 0;

            // Refresh gridview
            BindContainerData(db);

            // Close db connection
            db.Dispose();
        }

        /// <summary>
        /// Gridview function for updating container
        /// </summary>
        protected void gvContainer_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e)
        {
            // Get id
            this.ContainerId = Convert.ToInt32(e.Keys["ContainerId"]);

            TireServiceDB db = new TireServiceDB();

            Container container = new Container();

            // Fecth existing container tireset
            container = db.GetContainer(this.ContainerId);

            if (container != null)
            {
                container.Address = Convert.ToString(e.NewValues["Address"]);
                container.ZipCode = Convert.ToInt32(e.NewValues["ZipCode"]);
                container.City = Convert.ToString(e.NewValues["City"]);
                container.CountryId = Convert.ToInt32(e.NewValues["CountryId"]);
                container.InActive = Convert.ToBoolean(e.NewValues["InActive"]);
                container.NoneMoveableContainer = Convert.ToBoolean(e.NewValues["NoneMoveableContainer"]);

                // Calculate longitude and latitude for address if changed
                if (e.OldValues["Address"] != e.NewValues["Address"] | e.OldValues["ZipCode"] != e.NewValues["ZipCode"] | e.OldValues["City"] != e.NewValues["City"] | e.OldValues["CountryId"] != e.NewValues["CountryId"])
                {
                    try
                    {
                        string primaryAddress = container.Address + ", " + container.ZipCode + " " + container.City + ", " + db.GetCountryName(container.CountryId);
                        GoogleMaps googleMapAPI = new GoogleMaps(ConfigurationSettings.AppSettings["MapKey"]);
                        double[] LongLatPrimary = googleMapAPI.GetLongLatCoordinates(primaryAddress);
                        container.Longitude = LongLatPrimary[0];
                        container.Latitude = LongLatPrimary[1];
                    }
                    catch (Exception ex)
                    {
                        // Error calculating longitude and latitude - values will be set to null
                    }    
                }
            }
            else
            {
                // Customer subscription does not exists
                throw new ArgumentException("Lager eksistere ikke");
            }

            // Commit changes to database
            db.SubmitChanges();

            // End edit mode
            e.Cancel = true;
            gvContainer.CancelEdit();

            // Reset edit mode
            this.ContainerId = 0;

            // Refresh gridview
            BindContainerData(db);

            // Close db connection
            db.Dispose();
        }

        protected void gvContainerCargoRoom_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();
            try
            {
                int containerid = Convert.ToInt32(gvContainer.GetRowValues(gvContainer.FocusedRowIndex, "ContainerId"));
                BindContainerCargoRoom(db, containerid);
            }
            catch (Exception)
            {
                // Nothing - no container selected
            }
            
        }

        /// <summary>
        /// Gridview function that change field data for unbound fields
        /// </summary>
        protected void gvContainerCargoRoom_CustomUnboundColumnData(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewColumnDataEventArgs e)
        {
            // Format UnBoundColumn TireDimensions: Show tire dimensions
            if (e.Column.FieldName == "TireDimensions")
            {
                // Get tiresetstatusid
                object Size = e.GetListSourceFieldValue("Size");
                object Width = e.GetListSourceFieldValue("Width");
                object Height = e.GetListSourceFieldValue("Height");

                // Change field value
                try
                {
                    e.Value = Width.ToString() + " / " + Height.ToString() + " " + Size.ToString();
                }
                catch (Exception)
                {
                    e.Value = "";
                }
            }
        }

        #endregion

    }
}